package com.naiterui.ehp.bs.cms.modules.sys.controller;

import java.util.Arrays;

import javax.validation.Valid;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.Pattern;

import org.apache.commons.lang3.ArrayUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.naiterui.ehp.bp.constants.SwaggerTag;
import com.naiterui.ehp.bp.security.annotation.SysLog;
import com.naiterui.ehp.bp.security.utils.SecurityUtils;
import com.naiterui.ehp.bp.support.exception.BaseExceptionCodes;
import com.naiterui.ehp.bp.support.exception.BusinessException;
import com.naiterui.ehp.bs.cms.common.controller.AbstractController;
import com.naiterui.ehp.bs.cms.common.utils.JwtUser;
import com.naiterui.ehp.bs.cms.common.vo.PageParamsVO;
import com.naiterui.ehp.bs.cms.common.vo.PageVO;
import com.naiterui.ehp.bs.cms.modules.sys.entity.User;
import com.naiterui.ehp.bs.cms.modules.sys.service.ILogService;
import com.naiterui.ehp.bs.cms.modules.sys.service.IUserService;
import com.naiterui.ehp.bs.cms.modules.sys.vo.LogVO;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import springfox.documentation.annotations.ApiIgnore;

/**
 * 系统用户
 */
@Validated
@Api(tags = {SwaggerTag.CMS + SwaggerTag.SYS})
@RestController
@RequestMapping("/sys/user")
public class UserController extends AbstractController {

    @Autowired
    private IUserService userService;
    @Autowired
    private ILogService logService;

    /**
     * 所有用户列表
     *
     * @return
     */
    @ApiOperation(value = "获取用户列表")
    @SysLog("获取用户列表")
    @GetMapping("/list")
    @PreAuthorize("@p.check('sys:user:list')")
    public PageVO<User> list(PageParamsVO pageParamsVO, User user) {
        return this.userService.queryPage(pageParamsVO, user);
    }

    /**
     * 获取登录的用户信息
     *
     * @return
     */
    @ApiOperation(value = "获取登录的用户信息")
    @SysLog("获取登录的用户信息")
    @GetMapping("/info")
    public JwtUser info() {
        return SecurityUtils.getCurrentUser();
    }

    /**
     * 用户信息
     *
     * @return
     */
    @ApiOperation(value = "获取用户信息")
    @ApiImplicitParam(name = "userId", value = "用户ID", dataType = "long", paramType = "path", required = true)
    @SysLog("通过ID获取用户信息")
    @GetMapping("/info/{userId}")
    @PreAuthorize("@p.check('sys:user:info')")
    public User info(@PathVariable("userId") Long userId) {
        return this.userService.getById(userId);
    }

    /**
     * 修改登录用户密码
     */
    @ApiOperation(value = "修改登录用户密码")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "password", value = "原密码", dataType = "string", paramType = "query", required = true),
        @ApiImplicitParam(name = "newPassword", value = "新密码", dataType = "string", paramType = "query",
            required = true)})
    @SysLog("修改密码")
    @RequestMapping("/password")
    @PreAuthorize("@p.check('sys:user:password')")
    public void password(@NotEmpty(message = "原密码不能为null") String password,
        @Pattern(regexp = "^(?:(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?=.*[^A-Za-z0-9]))(?=^[^\\u4e00-\\u9fa5]{0,}$).{8,20}$", message = "密码过于简单有被盗风险，请保证密码大于8位，并且由大小写字母、数字，特殊符号组成")
        @NotEmpty(message = "新密码不能为null") String newPassword) throws BusinessException {
        // 更新密码
        User user = this.userService.loadUserByUsername(SecurityUtils.getCurrentUsername());
        this.userService.updatePassword(user, password, newPassword);
    }

    /**
     * 保存用户
     */
    @ApiOperation("保存用户")
    @SysLog("保存用户")
    @PostMapping("/save")
    @PreAuthorize("@p.check('sys:user:save')")
    public void save(@Valid @RequestBody User user) {
        this.userService.save(user);
    }

    /**
     * 修改用户
     */
    @ApiOperation("修改用户")
    @SysLog("修改用户")
    @PostMapping("/update")
    @PreAuthorize("@p.check('sys:user:update')")
    public void update(@Valid @RequestBody User user) throws BusinessException {
        this.userService.update(user);
    }

    /**
     * 删除用户
     */
    @ApiOperation(value = "删除用户")
    @ApiImplicitParam(name = "userIds", value = "用户ID集合", dataType = "array", paramType = "body", required = true)
    @SysLog("删除用户")
    @PostMapping("/delete")
    @PreAuthorize("@p.check('sys:user:delete')")
    public void delete(@RequestBody Long[] userIds) throws BusinessException {
        if (ArrayUtils.contains(userIds, SecurityUtils.getCurrentUser().getId())) {
            throw new BusinessException(BaseExceptionCodes.FAILED, "当前用户不能删除");
        }
        this.userService.removeByIds(Arrays.asList(userIds));
    }

    @ApiIgnore
    @GetMapping("/log")
    public PageVO<LogVO> userLog(PageParamsVO pageParamsVO) {
        return this.logService.queryUserLogPage(pageParamsVO);
    }

}
